Skip to content

Conversation

@maeryo
Copy link
Contributor

@maeryo maeryo commented Sep 24, 2025

According to https://modelcontextprotocol.io/specification/2025-06-18/basic/index#meta, the _meta parameter should be passable when calling tools. While the CallToolRequest class (in types.kt) currently includes _meta in its definition, SDK users cannot actually input _meta when invoking the callTool method.

This Pull Request adds a metadata parameter to the CallTool method and includes functionality to convert various data formats without loss.

Additionally, to encourage the use of valid Key name formats as defined by the protocol, validation for prefixes has been implemented.

Copy link
Contributor

@kpavlov kpavlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @maeryo
PR should always come with a test.
Let's revisit it after #294 is merged, so we have all the models coming

}

@OptIn(ExperimentalUnsignedTypes::class, ExperimentalSerializationApi::class)
private fun convertToJsonElement(value: Any?): JsonElement = when (value) {
Copy link
Contributor

@kpavlov kpavlov Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to extract JSON-related code to a separate class. It could be a separate PR with unit tests

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be moved to separate class

@kpavlov kpavlov added the question Further information is requested label Sep 29, 2025
@maeryo
Copy link
Contributor Author

maeryo commented Sep 29, 2025

Thank you for your feedback, @kpavlov
I've committed the test code.
Is there anything else I should check?

@kpavlov
Copy link
Contributor

kpavlov commented Sep 29, 2025

Thank you, @maeryo
Mock transport is very valuable. Let's double-check that it is thread-safe and can be used for parallel tests, and extract it to separate file.
Please also run ktlint fix, because ette build is failing because of this

@maeryo
Copy link
Contributor Author

maeryo commented Sep 29, 2025

@kpavlov, I just fixed ktlint. 🚀
Thank you!

Copy link
Contributor

@devcrocod devcrocod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take a look at my comments.
Also, it seems that your changes are breaking the tests

@devcrocod
Copy link
Contributor

Sorry, the integration tests broke because of the new field added. I’ll add a fix soon

@maeryo
Copy link
Contributor Author

maeryo commented Oct 23, 2025

@devcrocod I've addressed all your comments. Please let me know if any further changes are needed.

MAERYO and others added 7 commits October 23, 2025 14:12
- Add meta parameter support to callTool method with validation
- Implement MCP-compliant meta key validation (reserved prefixes, format rules)
- Enhance JSON conversion for complex data types with better error handling
- Add comprehensive test suite for meta parameter functionality
- Improve MockTransport to simulate proper initialization flow
- Update API signatures to include meta parameter support
@devcrocod devcrocod force-pushed the add-meta-in-call-tool-method branch from 127b270 to 7e087b4 Compare October 23, 2025 12:14
devcrocod
devcrocod previously approved these changes Oct 23, 2025
Method.Defined.PromptsList,
Method.Defined.CompletionComplete,
-> {
Method.Defined.PromptsGet, Method.Defined.PromptsList, Method.Defined.CompletionComplete -> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's actually better to have each case on a new line, because add/delete is more visible in diff

Comment on lines +595 to +596
val labelPattern = Regex("[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?")
val namePattern = Regex("[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regex patterns should be static constants

}

@OptIn(ExperimentalUnsignedTypes::class, ExperimentalSerializationApi::class)
private fun convertToJsonElement(value: Any?): JsonElement = when (value) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be moved to separate class

"formattedResult" : "11,000",
"precision" : 3,
"tags" : [ ]
"tags" : ["test", "calculator", "integration"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻 something was fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, previously the arrays were serialized as a string, and for some reason they were completely skipped in the process

client.callTool("test-tool", mapOf("arg" to "value"), validMeta)
}

assertTrue(result.isSuccess, "Valid meta keys should not cause exceptions")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertion for meta content is missing

}
}

class MockTransport : Transport {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MockTransport should be moved to separate file. It's a nice reusable stuff

}

class MockTransport : Transport {
private val _sentMessages = mutableListOf<JSONRPCMessage>()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a thread-safe collection

}

override fun onMessage(block: suspend (JSONRPCMessage) -> Unit) {
onMessageBlock = block
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should also capture and expose received messages (thread-safe)

kpavlov
kpavlov previously approved these changes Oct 23, 2025
Copy link
Contributor

@kpavlov kpavlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, folks!
I'm fine with merging this PR and making betterments in follow-up PR(s)

@kpavlov kpavlov added the bugfix Something was fixed 🎉 label Oct 23, 2025
@maeryo
Copy link
Contributor Author

maeryo commented Oct 23, 2025

@kpavlov Thanks for all the feedback. I'll prepare a follow-up PR after this is merged.

@devcrocod devcrocod dismissed stale reviews from kpavlov and themself via de5f8b5 October 23, 2025 13:03
@devcrocod devcrocod merged commit 407df7a into modelcontextprotocol:main Oct 23, 2025
3 checks passed
devcrocod pushed a commit that referenced this pull request Oct 23, 2025
## Changes
- Updated `DecimalFormatSymbols` to use period as decimal separator
(Locale.US)
- Fixed test expectations in `testComplexInputSchemaTool`:
  - `formattedResult`: `"11,000"` → `"11.000"`
- `tags`: Added actual test values `["test", "calculator",
"integration"]`
- Fixed test expectations in `testComplexNestedSchema`:
  - `formattedResult`: `"0,00"` → `"0.00"`

## Motivation
1. **Standard Decimal Notation**: Using a comma as a decimal separator
could be confusing as it's commonly used for thousands separators in
many locales. Standardizing on the period (`.`) follows international
conventions and makes the output clearer.

2. **Test Data Correction**: During the Validate PR workflow for #289,
discovered that the `tags` array in the `expectedContent` variable of
`testComplexInputSchemaTool()` was incorrectly set to an empty array,
which didn't match the actual input values being tested.

---------

Co-authored-by: MAERYO <[email protected]>
@kpavlov kpavlov mentioned this pull request Oct 23, 2025
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Something was fixed 🎉 question Further information is requested

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants